<?php

namespace App\Http\Middleware;

use Closure;

/**
 * API签名检测
 * Class CheckApiSignMiddleware
 * @package App\Http\Middleware
 */
class CheckApiSignMiddleware
{
	public function handle($request, Closure $next)
    {
    	if (env('IS_CHECK_SIGN', true)) {
			if($this->checkSign($request->all())) {
				return $next($request);
			} else {
				$this->returnError("无权限访问");
			}
		}  else {
			return $next($request);
		}
    }

	public function checkSign($param) {
		$timeStr = isset($param['timestamp']) ? $param['timestamp'] : "";
		if (!$timeStr) {
			return false;
		}

		//10分钟后签名失效
		if ($timeStr < (time() - 600)) {
			return false;
		}

		$sign = request()->input('sign');
		if (!$sign) {
			return false;
		}

		$randstr=request()->input('randstr');
		if (!$randstr) {
			return false;
		}

		$platform=request()->input('platform');
		if (!$platform) {
			return false;
		}

		$platformList = [
			'ios',
			'android',
			'h5',
			'pc'
		];

		if (!in_array($platform, $platformList)) {
			return false;
		}

		$tempParam = $this->formatData($param);
		$keyList = [];
		foreach ($tempParam as $key => $item) {
			$keyList[$key] = md5($key . '_' . $item);
		}

		asort($keyList);
		$keyStr = env('APP_SOCKET_KEY', 'SCARECROW_API_SOCKET');
		$checkSign = md5($keyStr.http_build_query($keyList).$keyStr);
		if ($sign == $checkSign) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 格式化数据,移除数据中的sign参数，以及值为空的数据
	 * @param $param
	 * @return mixed
	 */
	public function formatData($param) {
		unset($param['sign']);
		foreach ($param as $k => $item) {
			if ($item === "" || $item === null) {
				unset($param[$k]);
			}
		}
		return $param;
	}


	/**
	 * 返回错误信息
	 * @param $str
	 */
	/**
	 * 返回错误信息
	 * @param string $str
	 */
	protected function returnError($str = '签名验证失败', $code = API_CHECK_SIGN_FAIL) {
		die(ApiReturn('NO', $str, [], $code));
	}
}
